/*
 * @Author: 9ilk 3535851673@qq.com
 * @Date: 2024-11-07 17:09:37
 * @LastEditors: 9ilk 3535851673@qq.com
 * @LastEditTime: 2024-11-08 17:29:56
 * @FilePath: /zhuang/sharemem/Comm.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
#include <unistd.h>
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/ipc.h>
#include <cstdio>
#include <sys/shm.h>
using namespace std;

const string gfilename = "/home/zhuang/sharemem";
int procid = 0x6666;
int gshmSize = 4097; // shm大小
mode_t gmod = 0600;

// 转化成16进化制
string ToHex(key_t k)
{
  char buffer[64];
  snprintf(buffer, sizeof(buffer), "%x", k);
  return buffer;
}

class ShareMemory
{
private:
  void CreateShmHelper(int shmflg)
  {
    _key = ::ftok(gfilename.c_str(), procid);
    cout << "k :" << ToHex(_key) << endl;
    if (_key < 0)
    {
      cerr << "key error" << endl;
      return;
    }
    _shmid = ::shmget(_key, gshmSize, shmflg);
    if (_shmid < 0)
    {
      cerr << "shmget error" << endl;
      return;
    }
    cout << "shmid: " << _shmid << endl;
  }

public:
  ShareMemory()
      : _shmid(-1),
        _addr(nullptr),
        _key(0)
  {
  }

  ~ShareMemory()
  {
  }

  void CreateShm() // 创建shm
  {
    if (_shmid == -1) // 健壮性
      CreateShmHelper(IPC_CREAT | IPC_EXCL | gmod);
  }

  void GetShm() // 获取shm
  {
    CreateShmHelper(IPC_CREAT);
  }

  void AttachShm() // 挂接
  {
    _addr = shmat(_shmid, nullptr, 0);
    if ((long long)_addr == -1)
    {
      cerr << "attach error" << endl;
    }
  }

  void DetachShm() // 去关联
  {
    if (_addr != nullptr)
      shmdt(_addr);
  }

  void DeleteShm()
  {
    shmctl(_shmid, IPC_RMID, nullptr);
  }

  void *GetAddr()
  {
    return _addr;
  }

  void ShowMeta()
  {
    struct shmid_ds buffer;                      // 系统提供的数据类型
    int n = ::shmctl(_shmid, IPC_STAT, &buffer); // 通过buffer带出来
    if (n < 0)
      return;
    cout << "#####################" << endl;
    cout << buffer.shm_atime << endl;
    cout << buffer.shm_cpid << endl;
    cout << buffer.shm_ctime << endl;
    cout << buffer.shm_nattch << endl;
    cout << buffer.shm_perm.__key << endl;
    cout << "#####################" << endl;
  }

private:
  int _shmid;
  void *_addr;
  key_t _key;
};

ShareMemory Sm;
struct data
{
  char status[32];
  char lasttime[48];
  char image[1024];
};